package edu.vcu.csl.ess;

import edu.vcu.csl.ess.RawModel.*;

public class ReactionParser {

	/**
	 * Parses the reaction equations out into the variables necessary for the simulator to run.	  
	 * @param r The current reaction to parse.
	 */
	public static boolean parse(Reaction r){
		String[] reaction = r.equation.split("=>");

		if (reaction.length > 2){			
			r.error = "Too many => arrows";
			return false;
		}
		else if(reaction.length == 1){
			r.error = "No yields arrow (=>) found.";
			return false;
		}
		//Split on + sign and parse individual elements

		//Parse reactants (reaction[0])
		String[] terms = reaction[0].trim().split("\\+");//Hack avoids dangling meta character error
		boolean temp = checkAndAddElements(r, terms, false);
		if(!temp){return temp;}

		//Parse products (reaction[1])
		terms = reaction[1].trim().split("\\+");
		temp = checkAndAddElements(r, terms, true);
		if(!temp){return temp;}

		return true;

	}

	private static boolean checkAndAddElements(Reaction r, String[] terms,boolean trueIfProducts){

		boolean goBack = false;	//Hack var to break out of function

		int subStringLength;

		for (String t : terms){
			t=t.trim();
			subStringLength = 0;

			//Increment through first term until we don't see a digit. (Extract coefficient)
			for (char c : t.toCharArray()){
				if (!Character.isDigit(c)){break;}
				subStringLength++;				
			}

			//Finish extracting coefficient
			int coefficient = 0;
			if (subStringLength == 0){coefficient = 1;} //Handles case when variable does not have a digit coefficient
			else{
				try {
					coefficient = Integer.parseInt(t.substring(0,subStringLength));
				} catch (NumberFormatException e) {
					r.error = "Invalid coefficient.";
					return false;
				}
			}

			//Throws error for ++ condition
			if(t.trim().length() == 0){				
				r.error = "Too many + signs";
				return false;
			}

			//The rest of the string is therefore the species name
			String varName = t.substring(subStringLength,t.length()).trim();

			if (varName.equals("*")){break;}

			//Check to see if species name is legal per SBML reqs
			if(!JavaCodeParser.isValidName(varName)){
				r.error = "Invalid name.";
			}				

			//Check to see is var already exists to increment existing coefficient
			if (trueIfProducts){

				for(ReactionElement r1 : r.products){
					if(r1.species.equals(varName)){					
						r1.coefficient += coefficient;						
						goBack = true;
					}				
				}

			}
			else{

				for(ReactionElement r1 : r.reactants){				
					if(r1.species.equals(varName)){
						r1.coefficient += coefficient;						
						goBack = true;
					}				
				}

			}
			//Will be assigned true if a species already exists in the current reaction
			if (goBack){break;}

			ReactionElement temp = new ReactionElement();
			temp.coefficient = coefficient;			
			temp.species = varName;			

			if (trueIfProducts){
				r.products.add(temp);				
			}
			else{
				r.reactants.add(temp);				
			}

		}
		return true;
	}

	//	private static boolean checkVarName(Reaction r, String name){
	//
	//		Matcher matcher = Pattern.compile("[^a-zA-Z0-9_]").matcher(name);
	//
	//		if(matcher.find()){			
	//			r.error = "Illegal species name " + name + ".  Legal characters are a-z, A-Z, 0-9 and underscore.";
	//			return false;			
	//		}
	//		return true;
	//
	//	}
	//End Class
}
